package com.suray.wcs.service.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.suray.wcs.service.enums.DetailProcess;
import com.suray.wcs.service.enums.PrecessStatus;
import com.suray.wcs.service.manager.AsyncManager;
import com.suray.wcs.service.manager.factory.AsyncFactory;
import com.suray.wcs.service.system.entity.TaskDetailDB;
import com.suray.wcs.service.system.mapper.TaskDetailDBMapper;
import com.suray.wcs.service.system.service.TaskDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.UUID;

@Service
@Transactional
public class TaskDetailServiceImpl extends ServiceImpl<TaskDetailDBMapper, TaskDetailDB> implements TaskDetailService {
    @Autowired
    private TaskDetailDBMapper taskDetailDBMapper;

    @Override
    public List<TaskDetailDB> queryByTaskId(Integer taskId) {
        QueryWrapper<TaskDetailDB> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TaskDetailDB::getTaskId, taskId);
        return this.list(queryWrapper);
    }

    @Override
    public void updateTaskDetailCompleteTime(TaskDetailDB taskDetailDB) {
        taskDetailDB.setUpdateTime(new Date());
        taskDetailDB.setStatus(PrecessStatus.COMPLETE.getValue());
        taskDetailDB.setOperation("");
        updateById(taskDetailDB);
    }

    @Override
    public void updateTaskDetailCompleteTime(TaskDetailDB taskDetailDB, PrecessStatus precessStatus) {
        taskDetailDB.setUpdateTime(new Date());
        taskDetailDB.setStatus(precessStatus.getValue());
        taskDetailDB.setOperation("");
        updateById(taskDetailDB);
    }

    private TaskDetailDB findTaskDetailByProcessAndTaskId(DetailProcess process, Integer taskId) {
        QueryWrapper<TaskDetailDB> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TaskDetailDB::getTaskId, taskId)
                .eq(TaskDetailDB::getProcess, process.getDescription())
                .ne(TaskDetailDB::getStatus, PrecessStatus.COMPLETE);
        return taskDetailDBMapper.selectOne(queryWrapper);
    }

    @Override
    public TaskDetailDB getTaskDetail(Integer taskId, DetailProcess process, String parentId, String start, String end,
                                      PrecessStatus status, String deviceInfo, String operation) {
        TaskDetailDB taskDetailDB = findTaskDetailByProcessAndTaskId(process, taskId);
        if (taskDetailDB != null) {
            taskDetailDB.setStatus(status.getValue());
            taskDetailDB.setDeviceInfo(deviceInfo);
            taskDetailDB.setUpdateTime(new Date());
            taskDetailDB.setRemark(deviceInfo);
            updateById(taskDetailDB);
            return taskDetailDB;
        } else {
            taskDetailDB = buildTask(taskId, process, parentId, start, end, status, deviceInfo, operation);
            return taskDetailDB;
        }

    }

    @Override
    public TaskDetailDB buildTask(Integer taskId, DetailProcess process, String parentId, String start, String end,
                                  PrecessStatus status, String deviceInfo, String operation) {
        TaskDetailDB taskDetailDB = new TaskDetailDB();
        taskDetailDB.setTaskId(taskId);
        taskDetailDB.setProcess(process.getDescription());
        taskDetailDB.setParentId(parentId);
        taskDetailDB.setStart(start);
        taskDetailDB.setEnding(end);
        taskDetailDB.setStatus(status.getValue());
        taskDetailDB.setCreateTime(new Date());
        taskDetailDB.setDeviceInfo(deviceInfo);
        taskDetailDB.setOperation(operation);
        taskDetailDB.setUuid(UUID.randomUUID().toString());
        // 保存数据库
        AsyncManager.me().execute(AsyncFactory.recordTaskDetailOper(taskDetailDB));
        return taskDetailDB;
    }

    @Override
    public void deleteTaskDetailByTaskId(List<Integer> taskIds) {
        QueryWrapper<TaskDetailDB> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().in(TaskDetailDB::getTaskId, taskIds);
        taskDetailDBMapper.delete(queryWrapper);
    }
}
